package com.mutual.reins.interf.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.mutual.base.exception.BusinessException;
import com.mutual.reins.config.entity.FhReTen;
import com.mutual.reins.config.service.IFhReTenService;
import com.mutual.reins.danger.entity.*;
import com.mutual.reins.danger.service.*;
import com.mutual.reins.interf.entity.*;
import com.mutual.reins.interf.service.*;
import com.mutual.reins.trial.service.IPrptReinsShareService;
import com.mutual.reins.trial.service.IPrptReinsTrialService;
import com.mutual.reins.utils.*;
import com.mutual.reins.utils.constraint.ReinsConst;
import com.mutual.reins.utils.constraint.UserExceptionEnum;
import com.mutual.reinsapi.entity.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;


/**
 * 实现承保送再保投保单接口
 *
 * @author panchen
 * @since 2021-03-31
 */
@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class GeneratePrptDangerUnitServiceImpl implements IGeneratePrptDangerUnitService {

    @Autowired
    private IReinsInterFlogService iReinsInterFlogService;
    @Autowired
    private IReinsPolicyUnitService iReinsPolicyUnitService;
    @Autowired
    private IReinsPolicyItemService iReinsPolicyItemService;
    @Autowired
    private IReinsPolicyCededService iReinsPolicyCededService;
    @Autowired
    private IReinsPolicyCoinsService iReinsPolicyCoinsService;
    @Autowired
    private IReinsPolicyEngageService iReinsPolicyEngageService;
    @Autowired
    private IReinsPolicyFeeService iReinsPolicyFeeService;
    @Autowired
    private IReinsPolicyLimitService iReinsPolicyLimitService;
    @Autowired
    private IReinsPolicyPlanService iReinsPolicyPlanService;
    @Autowired
    private IPrptDangerUnitService iPrptDangerUnitService;
    @Autowired
    private IPrptDangerCoinsService iPrptDangerCoinsService;
    @Autowired
    private IPrptDangerItemService iPrptDangerItemService;
    @Autowired
    private IPrptDangerPlanService iPrptDangerPlanService;
    @Autowired
    private IPrptDangerTotService iPrptDangerTotService;
    @Autowired
    private IPrptReinsShareService iPrptReinsShareService;
    @Autowired
    private IPrptReinsTrialService iPrptReinsTrialService;
    @Autowired
    private IFhReTenService iFhReTenService;
    @Autowired
    private IReinsPolicyInterfService iReinsPolicyInterfService;
    /**
     * 投保单再保生成中间表，危险单位，日志表
     *
     * @param reinsPolicyInterfDtoVo 承保送再保中间表数据对象
     * @return reinsStatusDtoVo 返回核心提交核保调用再保接口返回信息对象
     */
    @Override
    public ReinsStatusDtoVo generatePrptDangerUnit(ReinsPolicyInterfDtoVo reinsPolicyInterfDtoVo) {
        //将ReinsPolicyInterfDtoVo转换ReinsPolicyInterfDto
        ReinsPolicyInterfDto reinsPolicyInterfDto = this.copyReinsPolicyInterfDto(reinsPolicyInterfDtoVo);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        log.info("投保单提交核保调出时间：{}", LocalDateTime.now().format(dateTimeFormatter));
        // 初始化返回信息
        ReinsStatusDto reinsStatusDto = new ReinsStatusDto();
        try {
            reinsStatusDto = this.generateReinsStatus(reinsPolicyInterfDto.getCerTiType(), reinsPolicyInterfDto.getCerTiNo(), "Y");
            // 再保中间表的日志表插入数据
            ReinsInterFlog reinsInterfLogDto = this.genReinsInterFlog(reinsPolicyInterfDto);
            // 再保生成中间表，危险单位，日志表
            this.saveAndGenPolicyDangerUnit(reinsPolicyInterfDto, reinsInterfLogDto);
        } catch (BusinessException  businessException) {
            reinsStatusDto.setStatus("N");
            throw new BusinessException(UserExceptionEnum.REINS_INTERF_MESSAGE.getCode(),UserExceptionEnum.REINS_INTERF_MESSAGE.getMessage());
        }
        log.info("投保单提交核保调出时间：{}", LocalDateTime.now().format(dateTimeFormatter));
        //将ReinsStatusDtoVo 转换ReinsStatusDto
        ReinsStatusDtoVo reinsStatusDtoVo = new ReinsStatusDtoVo();
        BeanUtil.copyProperties(reinsStatusDto, reinsStatusDtoVo);
        return reinsStatusDtoVo;
    }

    /**
     * 将ReinsPolicyInterfDtoVo转换ReinsPolicyInterfDto
     * @param reinsPolicyInterfDtoVo 承保送再保中间表数据对象
     * @return 再保内部使用对象
     */
    private ReinsPolicyInterfDto copyReinsPolicyInterfDto(ReinsPolicyInterfDtoVo reinsPolicyInterfDtoVo) {
        ReinsPolicyInterfDto reinsPolicyInterfDto = new ReinsPolicyInterfDto();
        reinsPolicyInterfDto.setCerTiNo(reinsPolicyInterfDtoVo.getCerTiNo());
        reinsPolicyInterfDto.setCerTiType(reinsPolicyInterfDtoVo.getCerTiType());
        ReinsPolicyUnit reinsPolicyUnit = new ReinsPolicyUnit();
        ReinsPolicyUnitVo reinsPolicyUnitVo = reinsPolicyInterfDtoVo.getReinsPolicyUnitVo();
        BeanUtil.copyProperties(reinsPolicyUnitVo, reinsPolicyUnit);
        reinsPolicyInterfDto.setReinsPolicyUnit(reinsPolicyUnit);
        List<ReinsPolicyItemVo> reinsPolicyItemVoList = reinsPolicyInterfDtoVo.getReinsPolicyItemVo();
        List<ReinsPolicyItem> reinsPolicyItemList = new ArrayList<>();
        if(ObjectUtil.isNotNull(reinsPolicyItemVoList) && !reinsPolicyItemVoList.isEmpty()) {
            for(ReinsPolicyItemVo reinsPolicyItemVo:reinsPolicyItemVoList){
                ReinsPolicyItem reinsPolicyItem = new ReinsPolicyItem();
                BeanUtil.copyProperties(reinsPolicyItemVo, reinsPolicyItem);
                reinsPolicyItemList.add(reinsPolicyItem);
            }
            reinsPolicyInterfDto.setReinsPolicyItem(reinsPolicyItemList);
        }
        List<ReinsPolicyFeeVo> reinsPolicyFeeVoList = reinsPolicyInterfDtoVo.getReinsPolicyFeeVo();
        List<ReinsPolicyFee> reinsPolicyFeeList = new ArrayList<>();
        if(ObjectUtil.isNotNull(reinsPolicyFeeVoList) && !reinsPolicyFeeVoList.isEmpty()) {
            for(ReinsPolicyFeeVo reinsPolicyFeeVo:reinsPolicyFeeVoList){
                ReinsPolicyFee reinsPolicyFee = new ReinsPolicyFee();
                BeanUtil.copyProperties(reinsPolicyFeeVo, reinsPolicyFee);
                reinsPolicyFeeList.add(reinsPolicyFee);
            }
            reinsPolicyInterfDto.setReinsPolicyFee(reinsPolicyFeeList);
        }
        List<ReinsPolicyPlanVo> reinsPolicyPlanVoList = reinsPolicyInterfDtoVo.getReinsPolicyPlanVo();
        List<ReinsPolicyPlan> reinsPolicyPlanList = new ArrayList<>();
        if(ObjectUtil.isNotNull(reinsPolicyPlanVoList) && !reinsPolicyPlanVoList.isEmpty()) {
            for(ReinsPolicyPlanVo reinsPolicyPlanVo:reinsPolicyPlanVoList){
                ReinsPolicyPlan reinsPolicyPlan = new ReinsPolicyPlan();
                BeanUtil.copyProperties(reinsPolicyPlanVo, reinsPolicyPlan);
                reinsPolicyPlanList.add(reinsPolicyPlan);
            }
            reinsPolicyInterfDto.setReinsPolicyPlan(reinsPolicyPlanList);
        }
        List<ReinsPolicyCoinsVo> reinsPolicyCoinsVoList = reinsPolicyInterfDtoVo.getReinsPolicyCoinsVo();
        List<ReinsPolicyCoins> reinsPolicyCoinsList = new ArrayList<>();
        if(ObjectUtil.isNotNull(reinsPolicyCoinsVoList) && !reinsPolicyCoinsVoList.isEmpty()) {
            for(ReinsPolicyCoinsVo reinsPolicyCoinsVo:reinsPolicyCoinsVoList){
                ReinsPolicyCoins reinsPolicyCoins = new ReinsPolicyCoins();
                BeanUtil.copyProperties(reinsPolicyCoinsVo, reinsPolicyCoins);
                reinsPolicyCoinsList.add(reinsPolicyCoins);
            }
            reinsPolicyInterfDto.setReinsPolicyCoins(reinsPolicyCoinsList);
        }
        List<ReinsPolicyLimitVo> reinsPolicyLimitVoList = reinsPolicyInterfDtoVo.getReinsPolicyLimitVo();
        List<ReinsPolicyLimit> reinsPolicyLimitList = new ArrayList<>();
        if(ObjectUtil.isNotNull(reinsPolicyLimitVoList) && !reinsPolicyLimitVoList.isEmpty()) {
            for(ReinsPolicyLimitVo reinsPolicyLimitVo:reinsPolicyLimitVoList){
                ReinsPolicyLimit reinsPolicyLimit = new ReinsPolicyLimit();
                BeanUtil.copyProperties(reinsPolicyLimitVo, reinsPolicyLimit);
                reinsPolicyLimitList.add(reinsPolicyLimit);
            }
            reinsPolicyInterfDto.setReinsPolicyLimit(reinsPolicyLimitList);
        }
        List<ReinsPolicyEngageVo> reinsPolicyEngageVoList = reinsPolicyInterfDtoVo.getReinsPolicyEngageVo();
        List<ReinsPolicyEngage> reinsPolicyEngageList = new ArrayList<>();
        if(ObjectUtil.isNotNull(reinsPolicyEngageVoList) && !reinsPolicyEngageVoList.isEmpty()) {
            for(ReinsPolicyEngageVo reinsPolicyEngageVo:reinsPolicyEngageVoList){
                ReinsPolicyEngage reinsPolicyEngage = new ReinsPolicyEngage();
                BeanUtil.copyProperties(reinsPolicyEngageVo, reinsPolicyEngage);
                reinsPolicyEngageList.add(reinsPolicyEngage);
            }
            reinsPolicyInterfDto.setReinsPolicyEngage(reinsPolicyEngageList);
        }
        List<ReinsPolicyCededVo> reinsPolicyCededVoList = reinsPolicyInterfDtoVo.getReinsPolicyCededVo();
        List<ReinsPolicyCeded> reinsPolicyCededList = new ArrayList<>();
        if(ObjectUtil.isNotNull(reinsPolicyCededVoList) && !reinsPolicyCededVoList.isEmpty()) {
            for(ReinsPolicyCededVo reinsPolicyCededVo:reinsPolicyCededVoList){
                ReinsPolicyCeded reinsPolicyCeded = new ReinsPolicyCeded();
                BeanUtil.copyProperties(reinsPolicyCededVo, reinsPolicyCeded);
                reinsPolicyCededList.add(reinsPolicyCeded);
            }
            reinsPolicyInterfDto.setReinsPolicyCeded(reinsPolicyCededList);
        }
        return reinsPolicyInterfDto;
    }

    /**
     * 再保生成中间表，危险单位，日志表
     *
     * @param reinsPolicyInterfDto 承保送再保信息
     * @param reinsInterfLogDto    再保系统日志表对象
     */
    public void saveAndGenPolicyDangerUnit(ReinsPolicyInterfDto reinsPolicyInterfDto, ReinsInterFlog reinsInterfLogDto) {
        try{
            iReinsInterFlogService.save(reinsInterfLogDto);
            log.info(">>>>>>>>>>中间表生成 begin{} >>>>>>>>>>>", reinsPolicyInterfDto.getCerTiNo());
            //删除原有中间表数据
            iReinsPolicyInterfService.deleteReinsPolicyInterf("PROPOSALNO",reinsPolicyInterfDto.getReinsPolicyUnit().getProposalNo());
            // 存储中间表数据
            this.saveReinsPolicyInterf(reinsPolicyInterfDto);
            log.info(">>>>>>>>>>中间表生成 end{} >>>>>>>>>>>", reinsPolicyInterfDto.getCerTiNo());
            log.info(">>>>>>>>>>危险单位生成 begin{} >>>>>>>>>>>", reinsPolicyInterfDto.getCerTiNo());
            this.genDangerUnit(reinsPolicyInterfDto);
            log.info(">>>>>>>>>>危险单位生成 end{} >>>>>>>>>>>", reinsPolicyInterfDto.getCerTiNo());
            // 更新日志表状态为生成通过
            reinsInterfLogDto.setRecordFlag("1");
            UpdateWrapper<ReinsInterFlog> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("CERTINO", reinsInterfLogDto.getCerTiNo());
            updateWrapper.eq("SERIALNO", reinsInterfLogDto.getSerialNo());
            updateWrapper.set("RECORDFLAG", "1");
            iReinsInterFlogService.update(updateWrapper);
        }catch (BusinessException  businessException){
            throw new BusinessException(UserExceptionEnum.REINS_INTERF_MESSAGE.getCode(), UserExceptionEnum.REINS_INTERF_MESSAGE.getMessage());
        }

    }

    /**
     * 业务送再保危险单位数据生成
     *
     * @param reinsPolicyInterfDto 更新日期后承保送再保信息
     */
    private void genDangerUnit(ReinsPolicyInterfDto reinsPolicyInterfDto) {
        Collection<PrptDangerDto> prptDangerDtoList = new ArrayList<>();
        PrptDangerDto prptDangerDto = new PrptDangerDto();
        this.genPrptDangerUnitInfo(prptDangerDto, reinsPolicyInterfDto.getReinsPolicyUnit());
        List<ReinsPolicyItem> reinsPolicyItemList = reinsPolicyInterfDto.getReinsPolicyItem();
        if (ObjectUtil.isNotNull(reinsPolicyItemList) && reinsPolicyItemList.size() > 0) {
            this.genPrptDangerItemInfo(prptDangerDto, reinsPolicyItemList);
        }
        prptDangerDtoList.add(prptDangerDto);
        List<ReinsPolicyFee> reinsPolicyFeeList = reinsPolicyInterfDto.getReinsPolicyFee();
        if (ObjectUtil.isNotNull(reinsPolicyFeeList) && reinsPolicyFeeList.size() > 0) {
            this.genPrptDangerTotInfo(prptDangerDtoList, reinsPolicyInterfDto.getReinsPolicyFee());
        }
        PrptDangerUnit prptDangerUnitNew = prptDangerDto.getPrptDangerUnit();
        List<ReinsPolicyCoins> reinsPolicyCoinsList = reinsPolicyInterfDto.getReinsPolicyCoins();
        // 从共保需要反算金额
        BigDecimal baseRate = new BigDecimal("100.00");
        if (ReinsConst.COINSFLAG_CG.equals(prptDangerUnitNew.getCoinsFlag())) {
            if (ObjectUtil.isNotNull(reinsPolicyCoinsList) && reinsPolicyCoinsList.size() > 0) {
                baseRate = BigDecimal.ZERO;
                for (ReinsPolicyCoins reinsPolicyCoins : reinsPolicyCoinsList) {
                    if ("1".equals(reinsPolicyCoins.getCoinsType()) || "2".equals(reinsPolicyCoins.getCoinsType())) {
                        baseRate = ReinsUtils.add(baseRate, reinsPolicyCoins.getCoinsRate());
                    }
                }
            }
            this.updateCoinsTot(prptDangerDto.getPrptDangerTotList(), baseRate);
        }
        //更新危险单位基本信息
        this.updateAmount(reinsPolicyInterfDto, reinsPolicyCoinsList, prptDangerDtoList, baseRate);
        //prptDangerCoins保额保费从prptDangerUnit中取（全单）
        if (!ReinsConst.COINSFLAG_DJ.equals(prptDangerUnitNew.getCoinsFlag())) {
            this.genPrptDangerCoinsInfo(reinsPolicyCoinsList, prptDangerDtoList);
        }
        prptDangerDto.setPrptDangerUnit(prptDangerUnitNew);
        genPrptDangerPlanInfo(reinsPolicyInterfDto.getReinsPolicyPlan(), prptDangerDtoList);
        // 删除原有数据
        this.deletePrptDangerDto(prptDangerDto.getPrptDangerUnit());
        //保存新数据
        this.savePrptDangerDto(prptDangerDtoList);
    }

    /**
     * 保存危险单位对象
     *
     * @param prptDangerDtoList 危险单位对象
     */
    private void savePrptDangerDto(Collection<PrptDangerDto> prptDangerDtoList) {
        for (PrptDangerDto prptDangerDto : prptDangerDtoList) {
            if (ObjectUtil.isNotNull(prptDangerDto.getPrptDangerUnit())) {
                iPrptDangerUnitService.save(prptDangerDto.getPrptDangerUnit());
            }
            if (ObjectUtil.isNotNull(prptDangerDto.getPrptDangerItemList()) && prptDangerDto.getPrptDangerItemList().size() > 0) {
                iPrptDangerItemService.saveBatch(prptDangerDto.getPrptDangerItemList());
            }
            if (ObjectUtil.isNotNull(prptDangerDto.getPrptDangerTotList()) && prptDangerDto.getPrptDangerTotList().size() > 0) {
                iPrptDangerTotService.saveBatch(prptDangerDto.getPrptDangerTotList());
            }
            if (ObjectUtil.isNotNull(prptDangerDto.getPrptDangerPlanList()) && prptDangerDto.getPrptDangerPlanList().size() > 0) {
                iPrptDangerPlanService.saveBatch(prptDangerDto.getPrptDangerPlanList());
            }
            if (ObjectUtil.isNotNull(prptDangerDto.getPrptDangerCoinsList()) && prptDangerDto.getPrptDangerCoinsList().size() > 0) {
                iPrptDangerCoinsService.saveBatch(prptDangerDto.getPrptDangerCoinsList());
            }
        }
    }

    /**
     * 删除危险单位原有数据
     *
     * @param prptDangerUnit 危险单位基本信息
     */
    private void deletePrptDangerDto(PrptDangerUnit prptDangerUnit) {
        Map<String, Object> columnMap = new HashMap<String, Object>(16) {{
            put("PROPOSALNO", prptDangerUnit.getProposalNo());
        }};

        iPrptReinsShareService.removeByMap(columnMap);
        iPrptReinsTrialService.removeByMap(columnMap);
        iPrptDangerCoinsService.removeByMap(columnMap);
        iPrptDangerPlanService.removeByMap(columnMap);
        iPrptDangerTotService.removeByMap(columnMap);
        iPrptDangerItemService.removeByMap(columnMap);
        iPrptDangerUnitService.removeByMap(columnMap);
    }

    /**
     * 通过投保单号得到危险单位缴费计划信息
     *
     * @param reinsPolicyPlanList 接口表缴费计划信息
     * @param prptDangerDtoList   危险单位对象
     */
    private void genPrptDangerPlanInfo(List<ReinsPolicyPlan> reinsPolicyPlanList, Collection<PrptDangerDto> prptDangerDtoList) {
        BigDecimal sumPlanFee = new BigDecimal("0.00");
        BigDecimal sumPremOfVat = new BigDecimal("0.00");
        BigDecimal sumVat = new BigDecimal("0.00");
        BigDecimal sumPremFreeVat = new BigDecimal("0.00");
        BigDecimal sumFreeVat = new BigDecimal("0.00");
        for (ReinsPolicyPlan reinsPolicyPlan : reinsPolicyPlanList) {
            sumPlanFee = ReinsUtils.addRound(sumPlanFee, reinsPolicyPlan.getPlanFee(), 2);
            sumPremOfVat = ReinsUtils.addRound(sumPremOfVat, reinsPolicyPlan.getPremOfVat(), 2);
            sumVat = ReinsUtils.addRound(sumVat, reinsPolicyPlan.getVat(), 2);
            sumPremFreeVat = ReinsUtils.addRound(sumPremFreeVat, reinsPolicyPlan.getPremFreeVat(), 2);
            sumFreeVat = ReinsUtils.addRound(sumFreeVat, reinsPolicyPlan.getFreeVat(), 2);
        }
        for (PrptDangerDto prptDangerDto : prptDangerDtoList) {
            BigDecimal dangerPremium = prptDangerDto.getPrptDangerUnit().getPremium();
            BigDecimal dangerPremOfVat = prptDangerDto.getPrptDangerUnit().getPremOfVat();
            //含税不免税保费
            BigDecimal dangerPremOfVat1 = ReinsUtils.addRound(prptDangerDto.getPrptDangerUnit().getPremOfVat(), prptDangerDto.getPrptDangerUnit().getVat(), 2);
            BigDecimal dangerVat = prptDangerDto.getPrptDangerUnit().getVat();
            BigDecimal dangerPremFreeVat = prptDangerDto.getPrptDangerUnit().getPremFreeVat();
            //含税免税保费
            BigDecimal dangerPremFreeVat1 = ReinsUtils.addRound(prptDangerDto.getPrptDangerUnit().getPremFreeVat(), prptDangerDto.getPrptDangerUnit().getFreeVat(), 2);
            BigDecimal dangerFreeVat = prptDangerDto.getPrptDangerUnit().getFreeVat();

            BigDecimal sumDangerPlan = BigDecimal.ZERO;
            BigDecimal sumDangerPremOfVat = BigDecimal.ZERO;
            BigDecimal sumDangerVat = BigDecimal.ZERO;
            BigDecimal sumDangerPremFreeVat = BigDecimal.ZERO;
            BigDecimal sumDangerFreeVat = BigDecimal.ZERO;
            Collection<PrptDangerPlan> prptDangerPlanList = new ArrayList<>();
            for (Iterator<ReinsPolicyPlan> planIterator = reinsPolicyPlanList.iterator(); planIterator.hasNext(); ) {
                ReinsPolicyPlan reinsPolicyPlan = planIterator.next();
                PrptDangerPlan prptDangerPlan = genPrptDangerPlan(prptDangerDto.getPrptDangerUnit(), reinsPolicyPlan);

                BigDecimal planFee;
                BigDecimal premOfVat;
                BigDecimal vat;
                BigDecimal premFreeVat;
                BigDecimal freeVat;
                if (planIterator.hasNext()) {
                    BigDecimal planRate = reinsPolicyPlan.getPlanFee().divide(sumPlanFee, 8, BigDecimal.ROUND_HALF_UP);
                    planFee = ReinsUtils.mulRound(dangerPremium, planRate, 2);
                    premOfVat = ReinsUtils.mulRound(dangerPremOfVat, planRate, 2);
                    //增值税用含税保费乘以占比减去不含税保费乘以占比
                    BigDecimal premOfVat1 = ReinsUtils.mulRound(dangerPremOfVat1, planRate, 2);
                    vat = ReinsUtils.subRound(premOfVat1, premOfVat, 2);
                    premFreeVat = ReinsUtils.mulRound(dangerPremFreeVat, planRate, 2);
                    //增值税用含税保费乘以占比减去不含税保费乘以占比
                    BigDecimal premFreeVat1 = ReinsUtils.mulRound(dangerPremFreeVat1, planRate, 2);
                    freeVat = ReinsUtils.subRound(premFreeVat1, premFreeVat, 2);
                    sumDangerPlan = ReinsUtils.add(sumDangerPlan, planFee);
                    sumDangerPremOfVat = ReinsUtils.add(sumDangerPremOfVat, premOfVat);
                    sumDangerVat = ReinsUtils.add(sumDangerVat, vat);
                    sumDangerPremFreeVat = ReinsUtils.add(sumDangerPremFreeVat, premFreeVat);
                    sumDangerFreeVat = ReinsUtils.add(sumDangerFreeVat, freeVat);
                } else {
                    planFee = ReinsUtils.subRound(dangerPremium, sumDangerPlan, 2);
                    premOfVat = ReinsUtils.subRound(dangerPremOfVat, sumDangerPremOfVat, 2);
                    vat = ReinsUtils.subRound(dangerVat, sumDangerVat, 2);
                    premFreeVat = ReinsUtils.subRound(dangerPremFreeVat, sumDangerPremFreeVat, 2);
                    freeVat = ReinsUtils.subRound(dangerFreeVat, sumDangerFreeVat, 2);
                }
                prptDangerPlan.setPremOfVat(premOfVat);
                prptDangerPlan.setVat(vat);
                prptDangerPlan.setPremFreeVat(premFreeVat);
                prptDangerPlan.setFreeVat(freeVat);
                prptDangerPlan.setPlanFee(planFee);
                prptDangerPlanList.add(prptDangerPlan);
            }
            prptDangerDto.setPrptDangerPlanList(prptDangerPlanList);
        }

    }

    /**
     * 生成危险单位缴费计划信息
     *
     * @param prptDangerUnit  危险单位基本信息
     * @param reinsPolicyPlan 接口表缴费计划
     * @return 危险单位缴费计划信息
     */
    private PrptDangerPlan genPrptDangerPlan(PrptDangerUnit prptDangerUnit, ReinsPolicyPlan reinsPolicyPlan) {
        PrptDangerPlan prptDangerPlan = new PrptDangerPlan();
        prptDangerPlan.setProposalNo(prptDangerUnit.getProposalNo());
        prptDangerPlan.setDangerNo(prptDangerUnit.getDangerNo());
        prptDangerPlan.setSerialNo(reinsPolicyPlan.getSerialNo());
        prptDangerPlan.setPayNo(reinsPolicyPlan.getPayNo());
        prptDangerPlan.setPlanDate(reinsPolicyPlan.getPlanDate());
        prptDangerPlan.setCurrency(reinsPolicyPlan.getCurrency());
        prptDangerPlan.setExamineComCode(reinsPolicyPlan.getExamineComCode());
        prptDangerPlan.setExamineUserCode(reinsPolicyPlan.getExamineUserCode());
        return prptDangerPlan;
    }

    /**
     * 危险单位共保信息
     *
     * @param reinsPolicyCoinsList 再保接口共保信息
     * @param prptDangerDtoList    危险单位对象
     */
    private void genPrptDangerCoinsInfo(List<ReinsPolicyCoins> reinsPolicyCoinsList, Collection<PrptDangerDto> prptDangerDtoList) {
        for (Iterator<ReinsPolicyCoins> coinsIterator = reinsPolicyCoinsList.iterator(); coinsIterator.hasNext(); ) {
            ReinsPolicyCoins reinsPolicyCoins = coinsIterator.next();
            String coinsCode = reinsPolicyCoins.getCoinsCode();
            BigDecimal coinsRate = reinsPolicyCoins.getCoinsRate();
            Map<String, PrptDangerCoins> sumCoinsValueMap = new HashMap<>(16);
            for (Iterator<PrptDangerDto> dangerIterator = prptDangerDtoList.iterator(); dangerIterator.hasNext(); ) {
                PrptDangerDto prptDangerDto = dangerIterator.next();
                if (prptDangerDto.getPrptDangerCoinsList() == null) {
                    prptDangerDto.setPrptDangerCoinsList(new ArrayList<>());
                }
                BigDecimal dangerCoinsAmount;
                BigDecimal dangerCoinsPremium;
                BigDecimal dangerCoinsPremOfVat;
                BigDecimal dangerCoinsVat;
                BigDecimal dangerCoinsPremFreeVat;
                BigDecimal dangerCoinsFreeVat;
                if (coinsIterator.hasNext()) {
                    if (dangerIterator.hasNext()) {
                        dangerCoinsAmount = ReinsUtils.rateMulRound(prptDangerDto.getPrptDangerUnit().getAmount(), coinsRate, 100, 2);
                        dangerCoinsPremium = ReinsUtils.rateMulRound(prptDangerDto.getPrptDangerUnit().getPremium(), coinsRate, 100, 2);
                        dangerCoinsPremOfVat = ReinsUtils.rateMulRound(prptDangerDto.getPrptDangerUnit().getPremOfVat(), coinsRate, 100, 2);
                        dangerCoinsVat = ReinsUtils.rateMulRound(prptDangerDto.getPrptDangerUnit().getVat(), coinsRate, 100, 2);
                        dangerCoinsPremFreeVat = ReinsUtils.rateMulRound(prptDangerDto.getPrptDangerUnit().getPremFreeVat(), coinsRate, 100, 2);
                        dangerCoinsFreeVat = ReinsUtils.rateMulRound(prptDangerDto.getPrptDangerUnit().getFreeVat(), coinsRate, 100, 2);
                        if (sumCoinsValueMap.containsKey(coinsCode)) {
                            PrptDangerCoins tempPrptDangerCoins = sumCoinsValueMap.get(coinsCode);
                            tempPrptDangerCoins.setCoinsAmount(ReinsUtils.add(tempPrptDangerCoins.getCoinsAmount(), dangerCoinsAmount));
                            tempPrptDangerCoins.setCoinsPremium(ReinsUtils.add(tempPrptDangerCoins.getCoinsPremium(), dangerCoinsPremium));
                            tempPrptDangerCoins.setPremOfVat(ReinsUtils.add(tempPrptDangerCoins.getPremOfVat(), dangerCoinsPremOfVat));
                            tempPrptDangerCoins.setVat(ReinsUtils.add(tempPrptDangerCoins.getVat(), dangerCoinsVat));
                            tempPrptDangerCoins.setPremFreeVat(ReinsUtils.add(tempPrptDangerCoins.getPremFreeVat(), dangerCoinsPremFreeVat));
                            tempPrptDangerCoins.setFreeVat(ReinsUtils.add(tempPrptDangerCoins.getFreeVat(), dangerCoinsFreeVat));
                        } else {
                            PrptDangerCoins tempPrptDangerCoins = new PrptDangerCoins();
                            tempPrptDangerCoins.setCoinsAmount(dangerCoinsAmount);
                            tempPrptDangerCoins.setCoinsPremium(dangerCoinsPremium);
                            tempPrptDangerCoins.setPremOfVat(dangerCoinsPremOfVat);
                            tempPrptDangerCoins.setVat(dangerCoinsVat);
                            tempPrptDangerCoins.setPremFreeVat(dangerCoinsPremFreeVat);
                            tempPrptDangerCoins.setFreeVat(dangerCoinsFreeVat);
                            sumCoinsValueMap.put(coinsCode, tempPrptDangerCoins);
                        }
                    } else {
                        if (sumCoinsValueMap.containsKey(coinsCode)) {
                            PrptDangerCoins tempPrptDangerCoins = sumCoinsValueMap.get(coinsCode);
                            dangerCoinsAmount = ReinsUtils.subRound(reinsPolicyCoins.getCoinsAmount(), tempPrptDangerCoins.getCoinsAmount(), 2);
                            dangerCoinsPremium = ReinsUtils.subRound(reinsPolicyCoins.getCoinsPremium(), tempPrptDangerCoins.getCoinsPremium(), 2);
                            dangerCoinsPremOfVat = ReinsUtils.subRound(reinsPolicyCoins.getPremOfVat(), tempPrptDangerCoins.getPremOfVat(), 2);
                            dangerCoinsVat = ReinsUtils.subRound(reinsPolicyCoins.getVat(), tempPrptDangerCoins.getVat(), 2);
                            dangerCoinsPremFreeVat = ReinsUtils.subRound(reinsPolicyCoins.getPremFreeVat(), tempPrptDangerCoins.getPremFreeVat(), 2);
                            dangerCoinsFreeVat = ReinsUtils.subRound(reinsPolicyCoins.getFreeVat(), tempPrptDangerCoins.getFreeVat(), 2);
                        } else {
                            dangerCoinsAmount = reinsPolicyCoins.getCoinsAmount();
                            dangerCoinsPremium = reinsPolicyCoins.getCoinsPremium();
                            dangerCoinsPremOfVat = reinsPolicyCoins.getPremOfVat();
                            dangerCoinsVat = reinsPolicyCoins.getVat();
                            dangerCoinsPremFreeVat = reinsPolicyCoins.getPremFreeVat();
                            dangerCoinsFreeVat = reinsPolicyCoins.getFreeVat();
                        }
                    }
                } else {
                    Map<String, BigDecimal> sumDangerCoins = genSumDangerCoins(prptDangerDto.getPrptDangerCoinsList());
                    dangerCoinsAmount = ReinsUtils.subRound(prptDangerDto.getPrptDangerUnit().getAmount(), sumDangerCoins.get("sumDangerCoinsAmount"), 2);
                    dangerCoinsPremium = ReinsUtils.subRound(prptDangerDto.getPrptDangerUnit().getPremium(), sumDangerCoins.get("sumDangerCoinsPremium"), 2);
                    dangerCoinsPremOfVat = ReinsUtils.subRound(prptDangerDto.getPrptDangerUnit().getPremOfVat(), sumDangerCoins.get("sumDangerCoinsPremOfVat"), 2);
                    dangerCoinsVat = ReinsUtils.subRound(prptDangerDto.getPrptDangerUnit().getVat(), sumDangerCoins.get("sumDangerCoinsVat"), 2);
                    dangerCoinsPremFreeVat = ReinsUtils.subRound(prptDangerDto.getPrptDangerUnit().getPremFreeVat(), sumDangerCoins.get("sumDangerCoinsPremFreeVat"), 2);
                    dangerCoinsFreeVat = ReinsUtils.subRound(prptDangerDto.getPrptDangerUnit().getFreeVat(), sumDangerCoins.get("sumDangerCoinsFreeVat"), 2);
                }
                PrptDangerCoins prptDangerCoins =
                        this.genPrptDangerCoins(reinsPolicyCoins, prptDangerDto.getPrptDangerUnit(), dangerCoinsAmount,
                                dangerCoinsPremium, dangerCoinsPremOfVat, dangerCoinsVat, dangerCoinsPremFreeVat, dangerCoinsFreeVat);
                prptDangerDto.getPrptDangerCoinsList().add(prptDangerCoins);
            }
        }
    }

    /**
     * 获取共保费用
     *
     * @param prptDangerCoinsList 危险单位coins
     * @return 费用Map
     */
    private Map<String, BigDecimal> genSumDangerCoins(Collection<PrptDangerCoins> prptDangerCoinsList) {
        Map<String, BigDecimal> sumDangerCoins = new HashMap<>(16);
        BigDecimal sumDangerCoinsAmount = new BigDecimal("0.00");
        BigDecimal sumDangerCoinsPremium = new BigDecimal("0.00");
        BigDecimal sumDangerCoinsPremOfVat = new BigDecimal("0.00");
        BigDecimal sumDangerCoinsVat = new BigDecimal("0.00");
        BigDecimal sumDangerCoinsPremFreeVat = new BigDecimal("0.00");
        BigDecimal sumDangerCoinsFreeVat = new BigDecimal("0.00");
        for (PrptDangerCoins tempPrptDangerCoins : prptDangerCoinsList) {
            sumDangerCoinsAmount = ReinsUtils.add(sumDangerCoinsAmount, tempPrptDangerCoins.getCoinsAmount());
            sumDangerCoinsPremium = ReinsUtils.add(sumDangerCoinsPremium, tempPrptDangerCoins.getCoinsPremium());
            sumDangerCoinsPremOfVat = ReinsUtils.add(sumDangerCoinsPremOfVat, tempPrptDangerCoins.getPremOfVat());
            sumDangerCoinsVat = ReinsUtils.add(sumDangerCoinsVat, tempPrptDangerCoins.getVat());
            sumDangerCoinsPremFreeVat = ReinsUtils.add(sumDangerCoinsPremFreeVat, tempPrptDangerCoins.getPremFreeVat());
            sumDangerCoinsFreeVat = ReinsUtils.add(sumDangerCoinsFreeVat, tempPrptDangerCoins.getFreeVat());
        }
        sumDangerCoins.put("sumDangerCoinsAmount", sumDangerCoinsAmount.setScale(2, BigDecimal.ROUND_HALF_UP));
        sumDangerCoins.put("sumDangerCoinsPremium", sumDangerCoinsPremium.setScale(2, BigDecimal.ROUND_HALF_UP));
        sumDangerCoins.put("sumDangerCoinsPremOfVat", sumDangerCoinsPremOfVat.setScale(2, BigDecimal.ROUND_HALF_UP));
        sumDangerCoins.put("sumDangerCoinsVat", sumDangerCoinsVat.setScale(2, BigDecimal.ROUND_HALF_UP));
        sumDangerCoins.put("sumDangerCoinsPremFreeVat", sumDangerCoinsPremFreeVat.setScale(2, BigDecimal.ROUND_HALF_UP));
        sumDangerCoins.put("sumDangerCoinsFreeVat", sumDangerCoinsFreeVat.setScale(2, BigDecimal.ROUND_HALF_UP));
        return sumDangerCoins;
    }

    /**
     * 危险单位共保表基本信息
     *
     * @param reinsPolicyCoins       接口共保信息
     * @param prptDangerUnit         危险单位基本信息
     * @param dangerCoinsAmount      共保保额
     * @param dangerCoinsPremium     共保保费
     * @param dangerCoinsPremOfVat   共保不含税保费
     * @param dangerCoinsVat         共保增值税
     * @param dangerCoinsPremFreeVat 共保免税保费
     * @param dangerCoinsFreeVat     共保免税金额
     * @return 危险单位共保表基本信息
     */
    private PrptDangerCoins genPrptDangerCoins(ReinsPolicyCoins reinsPolicyCoins, PrptDangerUnit prptDangerUnit, BigDecimal dangerCoinsAmount, BigDecimal dangerCoinsPremium, BigDecimal dangerCoinsPremOfVat, BigDecimal dangerCoinsVat, BigDecimal dangerCoinsPremFreeVat, BigDecimal dangerCoinsFreeVat) {
        PrptDangerCoins prptDangerCoins = new PrptDangerCoins();
        prptDangerCoins.setProposalNo(prptDangerUnit.getProposalNo());
        prptDangerCoins.setDangerNo(prptDangerUnit.getDangerNo());
        prptDangerCoins.setSerialNo(reinsPolicyCoins.getSerialNo());
        prptDangerCoins.setMainProposalNo(prptDangerUnit.getProposalNo());
        prptDangerCoins.setCoinsCode(reinsPolicyCoins.getCoinsCode());
        prptDangerCoins.setCoinsName(reinsPolicyCoins.getCoinsName());
        prptDangerCoins.setCoinsType(reinsPolicyCoins.getCoinsType());
        prptDangerCoins.setCoinsRate(reinsPolicyCoins.getCoinsRate());
        prptDangerCoins.setChiefFlag(reinsPolicyCoins.getChiefFlag());
        prptDangerCoins.setProportionFlag(reinsPolicyCoins.getProportionFlag());
        prptDangerCoins.setFlag("00");
        prptDangerCoins.setCurrency(reinsPolicyCoins.getCurrency());
        prptDangerCoins.setExamineComCode(reinsPolicyCoins.getExamineComCode());
        prptDangerCoins.setExamineUserCode(reinsPolicyCoins.getExamineUserCode());
        prptDangerCoins.setCoinsAmount(dangerCoinsAmount);
        prptDangerCoins.setCoinsPremium(dangerCoinsPremium);
        prptDangerCoins.setPremOfVat(dangerCoinsPremOfVat);
        prptDangerCoins.setVat(dangerCoinsVat);
        prptDangerCoins.setPremFreeVat(dangerCoinsPremFreeVat);
        prptDangerCoins.setFreeVat(dangerCoinsFreeVat);
        return prptDangerCoins;
    }


    /**
     * 更新危险单位基本信息
     *
     * @param reinsPolicyInterfDto 承保送再保对象
     * @param reinsPolicyCoinsList 接口表共保信息
     * @param prptDangerDtoList    危险单位对象
     * @param baseRate             我司占比
     */
    private void updateAmount(ReinsPolicyInterfDto reinsPolicyInterfDto, List<ReinsPolicyCoins> reinsPolicyCoinsList, Collection<PrptDangerDto> prptDangerDtoList, BigDecimal baseRate) {
        Map<String, BigDecimal> sumCoinsMap = new HashMap<>(16);
        if (ReinsConst.COINSFLAG_CG.equals(reinsPolicyInterfDto.getReinsPolicyUnit().getCoinsFlag())) {
            genSumCoinsMap(sumCoinsMap, reinsPolicyCoinsList);
        }
        BigDecimal sumFeeAmount = new BigDecimal("0.00");
        String dangerCurrency = "";
        for (ReinsPolicyFee reinsPolicyFee : reinsPolicyInterfDto.getReinsPolicyFee()) {
            sumFeeAmount = ReinsUtils.addRound(sumFeeAmount, reinsPolicyFee.getAmountEx(), 2);
            dangerCurrency = reinsPolicyFee.getTCurrency();
        }
        BigDecimal sumDangerShare = new BigDecimal("0.0000");
        BigDecimal sumDangerAmount = new BigDecimal("0.00");
        BigDecimal sumDangerPremium = new BigDecimal("0.00");
        BigDecimal sumDangerPremOfVat = new BigDecimal("0.00");
        BigDecimal sumDangerVat = new BigDecimal("0.00");
        BigDecimal sumDangerPremFreeVat = new BigDecimal("0.00");
        BigDecimal sumDangerFreeVat = new BigDecimal("0.00");

        for (Iterator<PrptDangerDto> dangerIterator = prptDangerDtoList.iterator(); dangerIterator.hasNext(); ) {
            PrptDangerDto prptDangerDto = dangerIterator.next();
            PrptDangerUnit prptDangerUnit = prptDangerDto.getPrptDangerUnit();
            BigDecimal dangerAmount = new BigDecimal("0.00");
            BigDecimal dangerPremium = new BigDecimal("0.00");
            BigDecimal dangerPremOfVat = new BigDecimal("0.00");
            BigDecimal dangerVat = new BigDecimal("0.00");
            BigDecimal dangerPremFreeVat = new BigDecimal("0.00");
            BigDecimal dangerFreeVat = new BigDecimal("0.00");
            BigDecimal dangerShare;
            for (PrptDangerTot prptDangerTot : prptDangerDto.getPrptDangerTotList()) {
                dangerAmount = ReinsUtils.addRound(dangerAmount, prptDangerTot.getAmountEx(), 2);
                dangerPremium = ReinsUtils.addRound(dangerPremium, prptDangerTot.getPremiumEx(), 2);
                dangerPremOfVat = ReinsUtils.addRound(dangerPremOfVat, prptDangerTot.getPremOfVatEx(), 2);
                dangerVat = ReinsUtils.addRound(dangerVat, prptDangerTot.getVatEx(), 2);
                dangerPremFreeVat = ReinsUtils.addRound(dangerPremFreeVat, prptDangerTot.getPremFreeVatEx(), 2);
                dangerFreeVat = ReinsUtils.addRound(dangerFreeVat, prptDangerTot.getFreeVatEx(), 2);
            }

            if (dangerIterator.hasNext()) {
                dangerShare = ReinsUtils.rateRound(dangerAmount, sumFeeAmount, 4);
                sumDangerShare = ReinsUtils.addRound(sumDangerShare, dangerShare, 4);
            } else {
                sumDangerShare = sumDangerShare.setScale(4, BigDecimal.ROUND_HALF_UP);
                dangerShare = ReinsUtils.subRound(new BigDecimal("100"), sumDangerShare, 4);
            }
            if (ReinsConst.COINSFLAG_CG.equals(reinsPolicyInterfDto.getReinsPolicyUnit().getCoinsFlag())) {
                if (dangerIterator.hasNext()) {
                    dangerAmount = ReinsUtils.rateRound(dangerAmount, baseRate, 2);
                    dangerPremium = ReinsUtils.rateRound(dangerPremium, baseRate, 2);
                    dangerPremOfVat = ReinsUtils.rateRound(dangerPremOfVat, baseRate, 2);
                    dangerVat = ReinsUtils.rateRound(dangerVat, baseRate, 2);
                    dangerPremFreeVat = ReinsUtils.rateRound(dangerPremFreeVat, baseRate, 2);
                    dangerFreeVat = ReinsUtils.rateRound(dangerFreeVat, baseRate, 2);
                    sumDangerAmount = ReinsUtils.add(sumDangerAmount, dangerAmount);
                    sumDangerPremium = ReinsUtils.add(sumDangerPremium, dangerPremium);
                    sumDangerPremOfVat = ReinsUtils.add(sumDangerPremOfVat, dangerPremOfVat);
                    sumDangerVat = ReinsUtils.add(sumDangerVat, dangerVat);
                    sumDangerPremFreeVat = ReinsUtils.add(sumDangerPremFreeVat, dangerPremFreeVat);
                    sumDangerFreeVat = ReinsUtils.add(sumDangerFreeVat, dangerFreeVat);
                } else {
                    dangerAmount = ReinsUtils.subRound(sumCoinsMap.get("sumCoinsAmount"), sumDangerAmount, 2);
                    dangerPremium = ReinsUtils.subRound(sumCoinsMap.get("sumCoinsPremium"), sumDangerPremium, 2);
                    dangerPremOfVat = ReinsUtils.subRound(sumCoinsMap.get("sumCoinsPremOfVat"), sumDangerPremOfVat, 2);
                    dangerVat = ReinsUtils.subRound(sumCoinsMap.get("sumCoinsVat"), sumDangerVat, 2);
                    dangerPremFreeVat = ReinsUtils.subRound(sumCoinsMap.get("sumCoinsPremFreeVat"), sumDangerPremFreeVat, 2);
                    dangerFreeVat = ReinsUtils.subRound(sumCoinsMap.get("sumCoinsFreeVat"), sumDangerFreeVat, 2);
                }
            }
            prptDangerUnit.setDangerShare(dangerShare);
            prptDangerUnit.setCurrency(dangerCurrency);
            prptDangerUnit.setAmount(dangerAmount);
            prptDangerUnit.setPremium(dangerPremium);
            prptDangerUnit.setPremOfVat(dangerPremOfVat);
            prptDangerUnit.setVat(dangerVat);
            prptDangerUnit.setPremFreeVat(dangerPremFreeVat);
            prptDangerUnit.setFreeVat(dangerFreeVat);
        }
    }

    /**
     * 遍历接口表Coins  获取金额信息
     *
     * @param sumCoinsMap          金额信息Map
     * @param reinsPolicyCoinsList 接口表Coins
     */
    private void genSumCoinsMap(Map<String, BigDecimal> sumCoinsMap, List<ReinsPolicyCoins> reinsPolicyCoinsList) {
        BigDecimal sumCoinsAmount = new BigDecimal("0.00");
        BigDecimal sumCoinsPremium = new BigDecimal("0.00");
        BigDecimal sumCoinsPremOfVat = new BigDecimal("0.00");
        BigDecimal sumCoinsVat = new BigDecimal("0.00");
        BigDecimal sumCoinsPremFreeVat = new BigDecimal("0.00");
        BigDecimal sumCoinsFreeVat = new BigDecimal("0.00");
        for (ReinsPolicyCoins reinsPolicyCoins : reinsPolicyCoinsList) {
            sumCoinsAmount = ReinsUtils.add(sumCoinsAmount, reinsPolicyCoins.getCoinsAmount());
            sumCoinsPremium = ReinsUtils.add(sumCoinsPremium, reinsPolicyCoins.getCoinsPremium());
            sumCoinsPremOfVat = ReinsUtils.add(sumCoinsPremOfVat, reinsPolicyCoins.getPremOfVat());
            sumCoinsVat = ReinsUtils.add(sumCoinsVat, reinsPolicyCoins.getVat());
            sumCoinsPremFreeVat = ReinsUtils.add(sumCoinsPremFreeVat, reinsPolicyCoins.getPremFreeVat());
            sumCoinsFreeVat = ReinsUtils.add(sumCoinsFreeVat, reinsPolicyCoins.getFreeVat());
        }
        sumCoinsMap.put("sumCoinsAmount", sumCoinsAmount.setScale(2, BigDecimal.ROUND_HALF_UP));
        sumCoinsMap.put("sumCoinsPremium", sumCoinsPremium.setScale(2, BigDecimal.ROUND_HALF_UP));
        sumCoinsMap.put("sumCoinsPremOfVat", sumCoinsPremOfVat.setScale(2, BigDecimal.ROUND_HALF_UP));
        sumCoinsMap.put("sumCoinsVat", sumCoinsVat.setScale(2, BigDecimal.ROUND_HALF_UP));
        sumCoinsMap.put("sumCoinsPremFreeVat", sumCoinsPremFreeVat.setScale(2, BigDecimal.ROUND_HALF_UP));
        sumCoinsMap.put("sumCoinsFreeVat", sumCoinsFreeVat.setScale(2, BigDecimal.ROUND_HALF_UP));

    }


    /**
     * 从共业务反算危险单位金额合计信息
     *
     * @param prptDangerTotList 危险单位金额合计信息
     * @param baseRate          我司占比
     */
    private void updateCoinsTot(Collection<PrptDangerTot> prptDangerTotList, BigDecimal baseRate) {
        for (PrptDangerTot prptDangerTot : prptDangerTotList) {
            prptDangerTot.setAmount(ReinsUtils.rateRound(prptDangerTot.getAmount(), baseRate, 2));
            prptDangerTot.setPremium(ReinsUtils.rateRound(prptDangerTot.getPremium(), baseRate, 2));
            prptDangerTot.setAmountEx(ReinsUtils.rateRound(prptDangerTot.getAmountEx(), baseRate, 2));
            prptDangerTot.setPremiumEx(ReinsUtils.rateRound(prptDangerTot.getPremiumEx(), baseRate, 2));
            prptDangerTot.setPremOfVat(ReinsUtils.rateRound(prptDangerTot.getPremOfVat(), baseRate, 2));
            prptDangerTot.setPremOfVatEx(ReinsUtils.rateRound(prptDangerTot.getPremOfVatEx(), baseRate, 2));
            prptDangerTot.setVat(ReinsUtils.rateRound(prptDangerTot.getVat(), baseRate, 2));
            prptDangerTot.setVatEx(ReinsUtils.rateRound(prptDangerTot.getVatEx(), baseRate, 2));
            prptDangerTot.setPremFreeVat(ReinsUtils.rateRound(prptDangerTot.getPremFreeVat(), baseRate, 2));
            prptDangerTot.setPremFreeVatEx(ReinsUtils.rateRound(prptDangerTot.getPremFreeVatEx(), baseRate, 2));
            prptDangerTot.setFreeVat(ReinsUtils.rateRound(prptDangerTot.getFreeVat(), baseRate, 2));
            prptDangerTot.setFreeVatEx(ReinsUtils.rateRound(prptDangerTot.getFreeVatEx(), baseRate, 2));
        }

    }

    /**
     * 通过投保单号得到危险单位金额合计信息
     *
     * @param prptDangerDtoList  危险单位集合
     * @param reinsPolicyFeeList 接口表金额合计信息集合
     */
    private void genPrptDangerTotInfo(Collection<PrptDangerDto> prptDangerDtoList, List<ReinsPolicyFee> reinsPolicyFeeList) {
        BigDecimal sumFeeAmount = new BigDecimal("0.00");
        BigDecimal sumFeePremium = new BigDecimal("0.00");
        BigDecimal sumFeePremOfVat = new BigDecimal("0.00");
        BigDecimal sumFeeVat = new BigDecimal("0.00");
        BigDecimal sumFeePremFreeVat = new BigDecimal("0.00");
        BigDecimal sumFeeFreeVat = new BigDecimal("0.00");

        Map<String, ReinsPolicyFee> reinsPolicyFeeMap = new HashMap<>(16);
        for (ReinsPolicyFee reinsPolicyFee : reinsPolicyFeeList) {
            //SCurrency是原币币别
            reinsPolicyFeeMap.put(reinsPolicyFee.getSCurrency(), reinsPolicyFee);
            //折合支付币别总金额
            sumFeeAmount = ReinsUtils.add(sumFeeAmount, reinsPolicyFee.getAmountEx());
            sumFeePremium = ReinsUtils.add(sumFeePremium, reinsPolicyFee.getPremiumEx());
            sumFeePremOfVat = ReinsUtils.add(sumFeePremOfVat, reinsPolicyFee.getPremOfVatEx());
            sumFeeVat = ReinsUtils.add(sumFeeVat, reinsPolicyFee.getVatEx());
            sumFeePremFreeVat = ReinsUtils.add(sumFeePremFreeVat, reinsPolicyFee.getPremFreeVatEx());
            sumFeeFreeVat = ReinsUtils.add(sumFeeFreeVat, reinsPolicyFee.getFreeVatEx());
        }
        for (Iterator<PrptDangerDto> dangerIterator = prptDangerDtoList.iterator(); dangerIterator.hasNext(); ) {
            PrptDangerDto prptDangerDto = dangerIterator.next();
            Map<String, PrptDangerTot> prptDangerTotMap = this.genPrptDangerTotMap(prptDangerDto.getPrptDangerItemList());
            for (Iterator<String> totIterator = prptDangerTotMap.keySet().iterator(); totIterator.hasNext(); ) {
                String sCurrency = totIterator.next();
                PrptDangerTot prptDangerTot = prptDangerTotMap.get(sCurrency);
                ReinsPolicyFee reinsPolicyFeeDto = reinsPolicyFeeMap.get(sCurrency);
                BigDecimal exchRate = reinsPolicyFeeDto.getExchRate();
                BigDecimal sumAmountEx = new BigDecimal("0.00");
                BigDecimal sumPremiumEx = new BigDecimal("0.00");
                BigDecimal sumPremOfVatEx = new BigDecimal("0.00");
                BigDecimal sumVatEx = new BigDecimal("0.00");
                BigDecimal sumPremFreeVatEx = new BigDecimal("0.00");
                BigDecimal sumFreeVatEx = new BigDecimal("0.00");
                BigDecimal amountEx;
                BigDecimal premiumEx;
                BigDecimal premOfVatEx;
                BigDecimal vatEx;
                BigDecimal premFreeVatEx;
                BigDecimal freeVatEx;

                if (!dangerIterator.hasNext() && !totIterator.hasNext()) {
                    amountEx = ReinsUtils.subRound(sumFeeAmount, sumAmountEx, 2);
                    premiumEx = ReinsUtils.subRound(sumFeePremium, sumPremiumEx, 2);
                    premOfVatEx = ReinsUtils.subRound(sumFeePremOfVat, sumPremOfVatEx, 2);
                    vatEx = ReinsUtils.subRound(sumFeeVat, sumVatEx, 2);
                    premFreeVatEx = ReinsUtils.subRound(sumFeePremFreeVat, sumPremFreeVatEx, 2);
                    freeVatEx = ReinsUtils.subRound(sumFeeFreeVat, sumFreeVatEx, 2);
                } else {
                    amountEx = ReinsUtils.mulRound(prptDangerTot.getAmount(), exchRate, 2);
                    premiumEx = ReinsUtils.mulRound(prptDangerTot.getPremium(), exchRate, 2);
                    premOfVatEx = ReinsUtils.mulRound(prptDangerTot.getPremOfVat(), exchRate, 2);
                    vatEx = ReinsUtils.mulRound(prptDangerTot.getVat(), exchRate, 2);
                    premFreeVatEx = ReinsUtils.mulRound(prptDangerTot.getPremFreeVat(), exchRate, 2);
                    freeVatEx = ReinsUtils.mulRound(prptDangerTot.getFreeVat(), exchRate, 2);

                    ReinsUtils.addRound(sumAmountEx, amountEx, 2);
                    ReinsUtils.addRound(sumPremiumEx, premiumEx, 2);
                    ReinsUtils.addRound(sumPremOfVatEx, premOfVatEx, 2);
                    ReinsUtils.addRound(sumVatEx, vatEx, 2);
                    ReinsUtils.addRound(sumPremFreeVatEx, premFreeVatEx, 2);
                    ReinsUtils.addRound(sumFreeVatEx, freeVatEx, 2);
                }
                prptDangerTot.setTCurrency(reinsPolicyFeeDto.getTCurrency());
                prptDangerTot.setExchRate(exchRate);
                prptDangerTot.setAmountEx(amountEx);
                prptDangerTot.setPremiumEx(premiumEx);
                prptDangerTot.setPremOfVatEx(premOfVatEx);
                prptDangerTot.setVatEx(vatEx);
                prptDangerTot.setPremFreeVatEx(premFreeVatEx);
                prptDangerTot.setFreeVatEx(freeVatEx);
                prptDangerTot.setExamineComCode(reinsPolicyFeeDto.getExamineComCode());
                prptDangerTot.setExamineUserCode(reinsPolicyFeeDto.getExamineUserCode());
            }
            prptDangerDto.setPrptDangerTotList(prptDangerTotMap.values());
        }
    }

    /**
     * 获取危险单位金额信息Map
     *
     * @param prptDangerItemList 标的信息集合
     * @return 危险单位金额信息Map
     */
    private Map<String, PrptDangerTot> genPrptDangerTotMap(Collection<PrptDangerItem> prptDangerItemList) {
        Map<String, PrptDangerTot> prptDangerTotMap = new HashMap<>(16);
        for (PrptDangerItem prptDangerItem : prptDangerItemList) {
            if (prptDangerTotMap.containsKey(prptDangerItem.getCurrency())) {
                PrptDangerTot prptDangerTot = prptDangerTotMap.get(prptDangerItem.getCurrency());
                if ("Y".equals(prptDangerItem.getCalculateFlag())) {
                    prptDangerTot.setAmount(ReinsUtils.add(prptDangerTot.getAmount(), prptDangerItem.getAmount()).setScale(2, BigDecimal.ROUND_HALF_UP));
                }
                prptDangerTot.setPremium(ReinsUtils.add(prptDangerTot.getPremium(), prptDangerItem.getPremium()).setScale(2, BigDecimal.ROUND_HALF_UP));
                prptDangerTot.setPremOfVat(ReinsUtils.add(prptDangerTot.getPremOfVat(), prptDangerItem.getPremOfVat()).setScale(2, BigDecimal.ROUND_HALF_UP));
                prptDangerTot.setVat(ReinsUtils.add(prptDangerTot.getVat(), prptDangerItem.getVat()).setScale(2, BigDecimal.ROUND_HALF_UP));
                prptDangerTot.setPremFreeVat(ReinsUtils.add(prptDangerTot.getPremFreeVat(), prptDangerItem.getPremFreeVat()).setScale(2, BigDecimal.ROUND_HALF_UP));
                prptDangerTot.setFreeVat(ReinsUtils.add(prptDangerTot.getFreeVat(), prptDangerItem.getFreeVat()).setScale(2, BigDecimal.ROUND_HALF_UP));
            } else {
                PrptDangerTot prptDangerTot = new PrptDangerTot();
                prptDangerTot.setProposalNo(prptDangerItem.getProposalNo());
                prptDangerTot.setDangerNo(prptDangerItem.getDangerNo());
                prptDangerTot.setSCurrency(prptDangerItem.getCurrency());
                if ("Y".equals(prptDangerItem.getCalculateFlag())) {
                    prptDangerTot.setAmount(prptDangerItem.getAmount());
                }
                prptDangerTot.setPremium(prptDangerItem.getPremium());
                prptDangerTot.setPremOfVat(prptDangerItem.getPremOfVat());
                prptDangerTot.setVat(prptDangerItem.getVat());
                prptDangerTot.setPremFreeVat(prptDangerItem.getPremFreeVat());
                prptDangerTot.setFreeVat(prptDangerItem.getFreeVat());

                prptDangerTotMap.put(prptDangerItem.getCurrency(), prptDangerTot);
            }
        }
        return prptDangerTotMap;
    }

    /**
     * 通过投保单号得到危险单位标的信息
     *
     * @param prptDangerDto       危险单位对象
     * @param reinsPolicyItemList 再保系统接口表标的信息
     */
    private void genPrptDangerItemInfo(PrptDangerDto prptDangerDto, List<ReinsPolicyItem> reinsPolicyItemList) {
        List<PrptDangerItem> prptDangerItemDtoList = new ArrayList<>();
        for (ReinsPolicyItem reinsPolicyItem : reinsPolicyItemList) {
            PrptDangerItem prptDangerItem = new PrptDangerItem();
            prptDangerItem.setProposalNo(prptDangerDto.getPrptDangerUnit().getProposalNo());
            prptDangerItem.setRiskCode(reinsPolicyItem.getRiskCode());
            prptDangerItem.setDangerNo(prptDangerDto.getPrptDangerUnit().getDangerNo());
            prptDangerItem.setSerialNo(reinsPolicyItem.getItemKindNo());
            prptDangerItem.setKindFlag("0");
            prptDangerItem.setKindCode(reinsPolicyItem.getKindCode());
            prptDangerItem.setKindName(reinsPolicyItem.getKindName());
            prptDangerItem.setItemCode(reinsPolicyItem.getItemCode());
            prptDangerItem.setItemDetailName(reinsPolicyItem.getItemDetailName());
            prptDangerItem.setPostCode(reinsPolicyItem.getPostCode());
            prptDangerItem.setAddressName(reinsPolicyItem.getAddressName());
            prptDangerItem.setCurrency(reinsPolicyItem.getCurrency());
            prptDangerItem.setAmount(reinsPolicyItem.getAmount());
            prptDangerItem.setPremium(reinsPolicyItem.getPremium());
            prptDangerItem.setCalculateFlag(reinsPolicyItem.getCalculateFlag());
            prptDangerItem.setFlag("00");
            prptDangerItem.setAddressCode(reinsPolicyItem.getAddressCode());
            prptDangerItem.setQuantity(reinsPolicyItem.getQuantity().longValue());
            prptDangerItem.setPremOfVat(reinsPolicyItem.getPremOfVat());
            prptDangerItem.setVat(reinsPolicyItem.getVat());
            prptDangerItem.setPremFreeVat(reinsPolicyItem.getPremFreeVat());
            prptDangerItem.setFreeVat(reinsPolicyItem.getFreeVat());
            prptDangerItem.setExamineComCode(reinsPolicyItem.getExamineComCode());
            prptDangerItem.setExamineUserCode(reinsPolicyItem.getExamineUserCode());
            prptDangerItemDtoList.add(prptDangerItem);
        }
        prptDangerDto.setPrptDangerItemList(prptDangerItemDtoList);
    }

    /**
     * 通过投保单号得到危险单位基本信息
     *
     * @param prptDangerDto   再保系统危险单位对象
     * @param reinsPolicyUnit 再保系统接口表基本信息对象
     */
    private void genPrptDangerUnitInfo(PrptDangerDto prptDangerDto, ReinsPolicyUnit reinsPolicyUnit) {
        PrptDangerUnit prptDangerUnit = new PrptDangerUnit();
        prptDangerUnit.setProposalNo(reinsPolicyUnit.getProposalNo());
        prptDangerUnit.setRiskCode(reinsPolicyUnit.getRiskCode());
        prptDangerUnit.setDangerNo(1);
        if (reinsPolicyUnit.getBusinessSource() == null || "".equals(Objects.requireNonNull(reinsPolicyUnit.getBusinessSource()).trim())) {
            prptDangerUnit.setBusiness("");
        } else {
            prptDangerUnit.setBusiness(reinsPolicyUnit.getBusinessSource().substring(0, 2));
        }
        prptDangerUnit.setStartDate(reinsPolicyUnit.getStartDate());
        prptDangerUnit.setEndDate(reinsPolicyUnit.getEndDate());
        prptDangerUnit.setShipCode(reinsPolicyUnit.getShipCode());
        prptDangerUnit.setShipCname(reinsPolicyUnit.getShipCname());
        prptDangerUnit.setBusinessNature(reinsPolicyUnit.getBusinessNature());
        prptDangerUnit.setGroupFlag(reinsPolicyUnit.getGroupFlag());
        prptDangerUnit.setCoinsFlag(reinsPolicyUnit.getCoinsFlag());

        if (reinsPolicyUnit.getBusinessFlag() == null || "".equals(reinsPolicyUnit.getBusinessFlag().trim())) {
            prptDangerUnit.setBusinessFlag("0");
        } else {
            prptDangerUnit.setBusinessFlag(reinsPolicyUnit.getBusinessFlag());
        }

        prptDangerUnit.setFlag("11");
        //新添字段flag1表示风险评估后是否保存
        prptDangerUnit.setFlag1("0000000000");

        prptDangerUnit.setPremOfVat(reinsPolicyUnit.getPremOfVat());
        prptDangerUnit.setVat(reinsPolicyUnit.getVat());
        prptDangerUnit.setVatRate(reinsPolicyUnit.getVatRate());
        prptDangerUnit.setPremFreeVat(reinsPolicyUnit.getPremFreeVat());
        prptDangerUnit.setFreeVat(reinsPolicyUnit.getFreeVat());

        //增加考核机构，考核人员
        prptDangerUnit.setExamineComCode(reinsPolicyUnit.getExamineComCode());
        prptDangerUnit.setExamineUserCode(reinsPolicyUnit.getExamineUserCode());
        //投保单风险等级
        this.setDefaultRiskInfo(prptDangerUnit, reinsPolicyUnit);
        prptDangerDto.setPrptDangerUnit(prptDangerUnit);
    }

    /**
     * 获取投保单风险等级
     *
     * @param prptDangerUnit  危险单位基本信息
     * @param reinsPolicyUnit 接口表基本信息
     */
    private void setDefaultRiskInfo(PrptDangerUnit prptDangerUnit, ReinsPolicyUnit reinsPolicyUnit) {
        //获取该险种默认的危险单位
        QueryWrapper<FhReTen> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("RISKCODE", reinsPolicyUnit.getRiskCode());
        queryWrapper.le("STARTDATE", reinsPolicyUnit.getStartDate());
        queryWrapper.ge("ENDDATE", reinsPolicyUnit.getStartDate());
        queryWrapper.eq("FLAG", "1");
        List<FhReTen> fhReTenList = iFhReTenService.list(queryWrapper);

        if (ObjectUtil.isNotNull(fhReTenList) && fhReTenList.size() > 0) {
            for (FhReTen fhReten : fhReTenList) {
                prptDangerUnit.setRiskClass(fhReten.getRiskClass());
                prptDangerUnit.setRiskClassDesc(fhReten.getRiskClassDesc());
                prptDangerUnit.setRiskLevel(fhReten.getRiskLevel());
                prptDangerUnit.setRiskLevelDesc(fhReten.getRiskLevelDesc());
                prptDangerUnit.setRetCurrency(fhReten.getCurrency());
                prptDangerUnit.setRetentionValue(fhReten.getRetentionValue());
                break;
            }
        } else {
            //在fhReTen中没有自留额配置时将将自留额设置为保单中的保额
            log.info("********设置默认自留额retentionValue：{}", reinsPolicyUnit.getAmount());
            prptDangerUnit.setRetentionValue(reinsPolicyUnit.getAmount());
            prptDangerUnit.setRetCurrency(reinsPolicyUnit.getCurrency());
        }
    }

    /**
     * 存储中间表数据
     *
     * @param reinsPolicyInterfDto 承保送再保中间表数据对象
     */
    private void saveReinsPolicyInterf(ReinsPolicyInterfDto reinsPolicyInterfDto) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 组织中间表数据插入数据库
        ReinsPolicyUnit reinsPolicyUnit = reinsPolicyInterfDto.getReinsPolicyUnit();
        // 将传输过来的日期从字符串转换到日期类型 begin
        reinsPolicyUnit.setOperateDate(LocalDate.parse(reinsPolicyUnit.getOperateDate().format(dateTimeFormatter), dateTimeFormatter));
        reinsPolicyUnit.setStartDate(LocalDate.parse(reinsPolicyUnit.getStartDate().format(dateTimeFormatter), dateTimeFormatter));
        reinsPolicyUnit.setEndDate(LocalDate.parse(reinsPolicyUnit.getEndDate().format(dateTimeFormatter), dateTimeFormatter));
        reinsPolicyUnit.setCreateDate(LocalDate.parse(reinsPolicyUnit.getCreateDate().format(dateTimeFormatter), dateTimeFormatter));

        //更新承保送再保中间表数据对象（日期）
        reinsPolicyInterfDto.setReinsPolicyUnit(reinsPolicyUnit);

        iReinsPolicyUnitService.save(reinsPolicyUnit);
        // 获得标的信息
        if (ObjectUtil.isNotNull(reinsPolicyInterfDto.getReinsPolicyItem())  && reinsPolicyInterfDto.getReinsPolicyItem().size() > 0) {
            iReinsPolicyItemService.saveBatch(reinsPolicyInterfDto.getReinsPolicyItem());
        }

        // 费用信息
        if ( ObjectUtil.isNotNull(reinsPolicyInterfDto.getReinsPolicyFee()) && reinsPolicyInterfDto.getReinsPolicyFee().size() > 0) {
            iReinsPolicyFeeService.saveBatch(reinsPolicyInterfDto.getReinsPolicyFee());
        }

        // 分期缴费信息
        if (ObjectUtil.isNotNull(reinsPolicyInterfDto.getReinsPolicyPlan()) && reinsPolicyInterfDto.getReinsPolicyPlan().size() > 0) {
            iReinsPolicyPlanService.saveBatch(reinsPolicyInterfDto.getReinsPolicyPlan());
        }

        // 联共保信息
        if (ObjectUtil.isNotNull(reinsPolicyInterfDto.getReinsPolicyCoins())  && reinsPolicyInterfDto.getReinsPolicyCoins().size() > 0) {
            iReinsPolicyCoinsService.saveBatch(reinsPolicyInterfDto.getReinsPolicyCoins());
        }

        // 投保单限额信息
        if (ObjectUtil.isNotNull(reinsPolicyInterfDto.getReinsPolicyLimit())  && reinsPolicyInterfDto.getReinsPolicyLimit().size() > 0) {
            iReinsPolicyLimitService.saveBatch(reinsPolicyInterfDto.getReinsPolicyLimit());
        }

        // 投保单特别约定信息
        if (ObjectUtil.isNotNull(reinsPolicyInterfDto.getReinsPolicyEngage()) && reinsPolicyInterfDto.getReinsPolicyEngage().size() > 0) {
            iReinsPolicyEngageService.saveBatch(reinsPolicyInterfDto.getReinsPolicyEngage());
        }

        // 分入业务信息
        if (ObjectUtil.isNotNull(reinsPolicyInterfDto.getReinsPolicyCeded()) && reinsPolicyInterfDto.getReinsPolicyCeded().size() > 0) {
            for (ReinsPolicyCeded reinsPolicyCeded : reinsPolicyInterfDto.getReinsPolicyCeded()) {
                reinsPolicyCeded.setOriStartDate(LocalDate.parse(reinsPolicyCeded.getOriStartDate().format(dateTimeFormatter), dateTimeFormatter));
                reinsPolicyCeded.setOriEndDate(LocalDate.parse(reinsPolicyCeded.getOriEndDate().format(dateTimeFormatter), dateTimeFormatter));
            }
            iReinsPolicyCededService.saveBatch(reinsPolicyInterfDto.getReinsPolicyCeded());
        }

    }


    /**
     * 获取核心提交核保调用再保接口返回信息对象
     *
     * @param cerTiType 单证业务类型
     * @param cerTiNo   单证业务号
     * @param status    状态
     * @return 返回信息对象
     */
    public ReinsStatusDto generateReinsStatus(String cerTiType, String cerTiNo, String status) {
        ReinsStatusDto reinsStatusDto = new ReinsStatusDto();
        reinsStatusDto.setCerTiNo(cerTiNo);
        reinsStatusDto.setCerTiType(cerTiType);
        reinsStatusDto.setStatus(status);
        return reinsStatusDto;
    }

    /**
     * 获取日志表对象
     *
     * @param reinsPolicyInterfDto 承保送再保中间表数据对象
     * @return ReinsInterFlog 日志表
     */
    private ReinsInterFlog genReinsInterFlog(ReinsPolicyInterfDto reinsPolicyInterfDto) {
        ReinsInterFlog reinsInterFlog = new ReinsInterFlog();
        // 再保中间表的日志表插入数据
        reinsInterFlog.setCerTiNo(reinsPolicyInterfDto.getCerTiNo());
        reinsInterFlog.setCerTiType(reinsPolicyInterfDto.getCerTiType());
        reinsInterFlog.setProposalNo(reinsPolicyInterfDto.getReinsPolicyUnit().getProposalNo());
        reinsInterFlog.setPolicyNo(reinsPolicyInterfDto.getReinsPolicyUnit().getPolicyNo());
        reinsInterFlog.setOperatorCode(reinsPolicyInterfDto.getReinsPolicyUnit().getCreaterCode());
        reinsInterFlog.setOperatorDate(reinsPolicyInterfDto.getReinsPolicyUnit().getOperateDate());
        reinsInterFlog.setOperatorName(reinsPolicyInterfDto.getReinsPolicyUnit().getUnderWritEname());
        // 初始化日志表时默认为不通过状态
        reinsInterFlog.setRecordFlag("0");

        Collection<ReinsInterFlog> reinsInterfLogList = iReinsInterFlogService.selectReinsInterFlogList(reinsPolicyInterfDto.getCerTiNo());
        if (ObjectUtil.isNotNull(reinsInterfLogList) && reinsInterfLogList.size() != 0) {
            int serialNo = reinsInterfLogList.iterator().next().getSerialNo() + 1;
            reinsInterFlog.setSerialNo(serialNo);
        } else {
            reinsInterFlog.setSerialNo(1);
        }

        return reinsInterFlog;
    }

}
